<template>
<div :class="[$style.container]">
  <iframe :src="src" frameborder="0" :class="[$style.iframe]" ref="iframe" v-if="src"></iframe>
  <empty-data v-else-if="unsupported">
    <template v-slot:icon><svg-icon icon="unsupported"></svg-icon></template>
    <span>不支持该类型文件在线编辑</span>
  </empty-data>
  <empty-data v-else-if="unauthorized">
    <template v-slot:icon><svg-icon icon="unauthorized"></svg-icon></template>
    <span>你没有该文件的在线编辑权限</span>
  </empty-data>
</div>
</template>

<script lang="ts">

import { getDocById, edit } from '@/api/doc'
import { Vue, Component, Provide, Watch, Ref, Prop } from 'vue-property-decorator'
import { hasPerm, PermissionName } from '@/config/acl'
import { canEdit, canPreview, canPrint } from '@/config/content-type'
import { expr } from '@/utils/url'
import { AppModule } from '@/store'
import md5 from 'md5'
import { getWatermark } from '@/api/watermark'

@Component
export default class Editor extends Vue {
  @Prop(String) id!: string

  @Ref() iframe!: HTMLIFrameElement

  @AppModule.State properties!: any

  current: any = null

  src = ''

  unsupported = true

  unauthorized = true

  expand = true

  get editorUrl () {
    return expr(this.properties?.deploy?.previewWeb || '') + '/editor'
  }

  get editorCallbackUrl () {
    return expr(this.properties?.deploy?.onlyOfficeCallback || '')
  }

  get onlyOfficeUrl () {
    return expr(this.properties?.deploy?.onlyOfficeWeb || '')
  }

  get canEdit () {
    return this.current && hasPerm('edit', this.current) && canEdit(this.current.name)
  }

  genSrc () {
    if (!this.current) return ''
    this.src = ''
    this.unauthorized = !hasPerm('edit', this.current)
    this.unsupported = !canEdit(this.current?.name)
    if (this.unsupported || this.unauthorized) return
    const response = {}
    edit(this.current?.id).then(url => {
      this.$oss.signatureUrl(url, { response }).then(url => {
        const query = {
          src: url,
          userid: this.$auth?.principle?.user?.id,
          username: this.$auth?.principle?.user?.username,
          uid: window.btoa(JSON.stringify({
            id: this.current?.id, // 唯一标识
            url: md5(url)
          })),
          callbackUrl: this.editorCallbackUrl,
          onlyOfficeUrl: this.onlyOfficeUrl,
          filename: this.current?.name
        }
        this.watermarkAttrs().then(({ watermarkDisabled, watermark }) => {
          if (watermark) Object.assign(query, { watermark })
          if (watermarkDisabled) Object.assign(query, { watermarkDisabled: 1 })
          const q = Object.entries(query).map(([k, v]) => {
            return encodeURIComponent(k) + '=' + encodeURIComponent(v)
          }).join('&')
          this.src = this.editorUrl + '?' + q
        })
      })
    })
  }

  watermarkAttrs () {
    const getDefault = () => {
      const watermarkDisabled = !!this.properties?.deploy?.watermarkDisabled
      const content = !watermarkDisabled && this.properties?.deploy?.watermark
      const ret: any = { watermarkDisabled }
      if (content) {
        ret.watermark = window.btoa(JSON.stringify({ content }))
      }
      return ret
    }
    const isEnt = this.current?.ownType === 'enterprise'
    if (!isEnt) return Promise.resolve(getDefault())
    return getWatermark(this.current?.ownId).then(data => {
      if (!data) return getDefault()
      if (!data?.enabled) {
        return { watermarkDisabled: true }
      } else {
        return {
          watermarkDisabled: false,
          watermark: encodeURIComponent(JSON.stringify(data))
        }
      }
    })
  }

  loadData () {
    if (!this.id) return
    getDocById(Number(this.id)).then(data => {
      this.current = data || null
    })
  }

  created () {
    this.loadData()
  }

  mounted () {
    const handler = (e: MessageEvent) => {
      if (e.data === 'doc_save') {
        this.$message.success('已保存')
      }
    }
    window.addEventListener('message', handler)
    this.$once('hook:beforeDestroy', function () {
      window.removeEventListener('message', handler)
    })
  }

  @Watch('current') currentChange () {
    if (this.current) this.genSrc()
  }
}
</script>

<style lang="scss" module>
@import "~@/styles/vars.scss";

.container {
  overflow: hidden;
  height: 100vh;
  box-sizing: border-box;
}

.iframe {
  width: 100%;
  height: 100%;
}
</style>
